package net.maku.events.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import lombok.AllArgsConstructor;
import net.maku.events.vo.AlreadyAnswerQuestionBankOptionVO;
import net.maku.events.vo.UserAnswerQuestionBankOptionVO;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.events.convert.UserContestQuestionOptionConvert;
import net.maku.events.entity.UserContestQuestionOptionEntity;
import net.maku.events.query.UserContestQuestionOptionQuery;
import net.maku.events.vo.UserContestQuestionOptionVO;
import net.maku.events.dao.UserContestQuestionOptionDao;
import net.maku.events.service.UserContestQuestionOptionService;
import net.maku.framework.security.user.SecurityUser;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户所答竞赛题选项
 *
 * @author 阿沐 babamu@126.com
 * @since 1.0.0 2025-03-22
 */
@Service
@AllArgsConstructor
public class UserContestQuestionOptionServiceImpl extends BaseServiceImpl<UserContestQuestionOptionDao, UserContestQuestionOptionEntity> implements UserContestQuestionOptionService {

    @Override
    public PageResult<UserContestQuestionOptionVO> page(UserContestQuestionOptionQuery query) {
        IPage<UserContestQuestionOptionEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));

        return new PageResult<>(UserContestQuestionOptionConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }

    private LambdaQueryWrapper<UserContestQuestionOptionEntity> getWrapper(UserContestQuestionOptionQuery query) {
        LambdaQueryWrapper<UserContestQuestionOptionEntity> wrapper = Wrappers.lambdaQuery();
        return wrapper;
    }

    @Override
    public boolean save(Long userContestQuestionId, List<UserAnswerQuestionBankOptionVO> options) {
        List<UserContestQuestionOptionEntity> entityList = BeanUtil.copyToList(options, UserContestQuestionOptionEntity.class);
        entityList.forEach(item -> {
            item.setUserContestQuestionId(userContestQuestionId);
            item.setUserId(SecurityUser.getUserId());
            item.setContestOptionId(item.getId());
            item.setId(null);
        });
        this.saveBatch(entityList);
        Set<Long> rightOptionIds = options.stream()
                .filter(item -> item.getWhetherCorrectAnswer() == 1)
                .map(UserAnswerQuestionBankOptionVO::getId)
                .collect(Collectors.toSet());
        Set<Long> selectedCorrectIds = options.stream()
                .filter(item -> item.getWhetherSelected() == 1)
                .map(UserAnswerQuestionBankOptionVO::getId)
                .collect(Collectors.toSet());
        boolean hasWrongSelection = options.stream()
                .anyMatch(item -> item.getWhetherSelected() == 1 && item.getWhetherCorrectAnswer() == 0);
        return !hasWrongSelection && selectedCorrectIds.equals(rightOptionIds);
    }

    @Override
    public Map<Long, List<AlreadyAnswerQuestionBankOptionVO>> getAlreadyAnswerOption(List<Long> userAnswerQuestionIdList) {
        List<UserContestQuestionOptionEntity> questionOptionEntityList = this.list(new LambdaQueryWrapper<UserContestQuestionOptionEntity>().in(UserContestQuestionOptionEntity::getUserContestQuestionId, userAnswerQuestionIdList));
        if (CollectionUtils.isEmpty(questionOptionEntityList)) {
            return null;
        }
        List<AlreadyAnswerQuestionBankOptionVO> voList = BeanUtil.copyToList(questionOptionEntityList, AlreadyAnswerQuestionBankOptionVO.class);
        voList.forEach(item -> {
            item.setId(item.getContestOptionId());
        });
        return voList.stream().collect(Collectors.groupingBy(AlreadyAnswerQuestionBankOptionVO::getUserContestQuestionId));
    }


}